package net.guerlab.loadbalancer;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * round robin Load Balancer
 *
 * @param <T>
 *         target class
 * @param <C>
 *         choose reference object
 * @author guer
 */
public class RoundRobinLoadBalancer<T, C> extends AbstractLoadBalancer<T, C> {

    private final AtomicInteger position = new AtomicInteger();

    /**
     * instantiation Load Balancer with CopyOnWriteArrayList
     */
    public RoundRobinLoadBalancer() {
        super();
    }

    /**
     * instantiation Load Balancer with appoint list
     *
     * @param targetList
     *         target object list
     */
    public RoundRobinLoadBalancer(List<TargetWrapper<T>> targetList) {
        super(targetList);
    }

    @Override
    protected T choose0(List<TargetWrapper<T>> activeTargetList, C chooseReferenceObject) {
        int pos = this.position.incrementAndGet();
        if (pos < 0) {
            pos = pos & Integer.MAX_VALUE;
        }
        TargetWrapper<T> wrapper = targetList.get(pos % targetList.size());
        return wrapper == null ? null : wrapper.getTarget();
    }
}
